﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Windows.Forms;
using Resonance.TrainNode.Contracts.Services;
using Resonance.TrainNode.ServiceClients;
using Resonance.TrainNode.Contracts.Entities;
using System.IO;

namespace Resonance.TrainNode.Test
{
	public partial class MgmtConsole : Form
	{
		private List<string> sessionGUIDs = new List<string>();
		ITrainNodeService svcLocal;
		ITrainNodeService svcRemote1;

		public MgmtConsole()
		{
			InitializeComponent();
			svcLocal = TrainNodeServiceFactory.GetNodeSvc("local");
			svcRemote1 = TrainNodeServiceFactory.GetNodeSvc("toshiba");
		}

		private void btnRefresh_Click(object sender, EventArgs e)
		{
			StringBuilder sb = new StringBuilder();

			PrintSessionStatus(svcLocal, sb);
			PrintSessionStatus(svcRemote1, sb);

			textBox1.Text = sb.ToString();
		}

		private void PrintSessionStatus(ITrainNodeService svc, StringBuilder sb)
		{
			TrainSession[] sessions = svc.GetSessions();

			foreach (TrainSession session in sessions)
			{
				sb.AppendLine(string.Format("Session GUID: {0} -- Description: {2}  -- State: {1}", session.ID, session.State.ToString(), session.Description));
				sb.AppendLine();
				sb.AppendLine();

				// order by epoch count
				IEnumerable<TrainJob> jobs = svc.GetSessionJobs(session.ID).AsParallel().OrderBy(j => j.CurrentEpoch);

				foreach (TrainJob job in jobs)
				{
					sb.AppendLine(string.Format("Job GUID: {0}  --  State: {1} -- Epoch {2} --  Error: {3:F8}", job.ID, job.State.ToString(), job.CurrentEpoch, job.CurrentError));
					if (job.State == JobStateEnum.Completed)
					{
						NNet net = svc.GetJobTrainResult(session.ID, job.ID);
						sb.AppendLine(string.Format("\t Layers: {0},  NeuronCount: {1},  Learning rate: {2:F4},  Momentum: {3:F4}",
											net.Layers.Length, net.Layers[0].Neurons.Length, job.TrainParams.LearningRate,
											job.TrainParams.Momentum));
					}
				}
				sb.AppendLine();
				sb.AppendLine("**************");
				sb.AppendLine();

			}
		}


		private void btnDeleteSessions_Click(object sender, EventArgs e)
		{
			TrainSession[] localSessions = svcLocal.GetSessions();
			TrainSession[] remoteSessions = svcRemote1.GetSessions();

			foreach (TrainSession session in localSessions)
			{
				svcLocal.RemoveSession(session.ID);
			}

			foreach (TrainSession session in remoteSessions)
			{
				svcRemote1.RemoveSession(session.ID);
			}
		}

		private void btnSerializeNet_Click(object sender, EventArgs e)
		{
			NNet net = null;

			ITrainNodeService svc = svcLocal;
			TrainSession[] sessions = svc.GetSessions();
			foreach (TrainSession session in sessions)
			{
				TrainJob[] jobs = svc.GetSessionJobs(session.ID);
				TrainJob job = (from j in jobs where j.ID == txtGUID.Text select j).FirstOrDefault();
				if (job != null)
				{
					net = svc.GetJobTrainResult(session.ID, job.ID);
					break;
				}
			}

			if (net == null)
			{
				svc = svcRemote1;
				sessions = svc.GetSessions();
				foreach (TrainSession session in sessions)
				{
					TrainJob[] jobs = svc.GetSessionJobs(session.ID);
					TrainJob job = (from j in jobs where j.ID == txtGUID.Text select j).FirstOrDefault();
					if (job != null)
					{
						net = svc.GetJobTrainResult(session.ID, job.ID);
						break;
					}
				}
			}

			if (net != null)
			{
				if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
				{
					string outputFile = saveFileDialog1.FileName;
					XmlSerializer xmlSer = new XmlSerializer(typeof(NNet));
					TextWriter wrt = new StreamWriter(outputFile, false);
					xmlSer.Serialize(wrt, net);
					wrt.Close();
				}
			}
		}
	}
}
